package org.pentaho.cws.repo;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.pentaho.platform.api.repository2.unified.IUnifiedRepository;
import org.pentaho.platform.api.repository2.unified.RepositoryFile;
import org.pentaho.platform.api.repository2.unified.data.simple.SimpleRepositoryFileData;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.repository2.unified.webservices.DefaultUnifiedRepositoryWebService;
import org.pentaho.platform.repository2.unified.webservices.RepositoryFileAclDto;
import org.pentaho.platform.repository2.unified.webservices.RepositoryFileDto;
import org.pentaho.platform.repository2.unified.webservices.RepositoryFileTreeAdapter;
import org.pentaho.platform.repository2.unified.webservices.RepositoryFileTreeDto;

@Path("/cws/api/repo")
public class RepositoryServiceImpl {
  
  protected RepositoryFileTreeAdapter repositoryFileTreeAdapter = new RepositoryFileTreeAdapter();
  protected IUnifiedRepository repo = PentahoSystem.get(IUnifiedRepository.class);
  DefaultUnifiedRepositoryWebService repoWS = new DefaultUnifiedRepositoryWebService();

  @GET
  @Path("files")
  @Produces("application/xml,application/json")
  public RepositoryFileTreeDto getFileTree(@QueryParam("path") String path, @QueryParam("depth") Integer depth, @QueryParam("filter") String filter) {
    
    if(filter == null) {
      filter = "*";
    }
    if(depth == null) {
      depth = -1; //search all
    }
    if(path == null) {
      path = "/";
    }
    
    return repoWS.getTree(path, depth, filter);
  }
  
  @GET
  @Path("files/{id}")
  @Produces("application/xml,application/json")
  public RepositoryFileDto getFile(@PathParam("id") String id) {
    return repoWS.getFileById(id);
  }
  
  @GET
  @Path("files/{id}/attr")
  @Consumes("text/plain")
  public RepositoryFileDto getFileAttributes(@PathParam("id") String id) {
    return repoWS.getFileById(id);
  }
  
  @GET
  @Path("files/{id}/acl")
  @Consumes("text/plain")
  public RepositoryFileAclDto getFileAcls(@PathParam("id") String id) {
    return repoWS.getAcl(id);
  }
  
  @GET
  @Path("files/{id}/data/text")
  @Consumes("text/plain")
  @Produces("text/plain")
  public String getFileData(@PathParam("id") String id) throws IOException {
    SimpleRepositoryFileData fileData = repo.getDataForRead(id, SimpleRepositoryFileData.class);
    return IOUtils.toString(fileData.getStream());
  }
  
  @PUT
  @Path("files/{id}/data")
  @Consumes("text/plain")
  public void setFileText(@PathParam("id") String id, String text) throws UnsupportedEncodingException {
    RepositoryFile file = repo.getFileById(id);
    
    ByteArrayInputStream bis = new ByteArrayInputStream(text.getBytes("UTF-8"));
    final SimpleRepositoryFileData payload = new SimpleRepositoryFileData(bis, "UTF-8", "text/xml");
    
    repo.updateFile(file, payload, "Updating text");
  }
  
  @POST
  @Path("files/{path}")
  @Consumes( { "text/plain", "application/x-www-form-urlencoded" } )
  public void newFile(@PathParam("path") String path, String text) throws UnsupportedEncodingException {
    String npath = FilenameUtils.normalizeNoEndSeparator(path);
    String fileName = FilenameUtils.getName(npath);
    String parentPath = path.substring(0, FilenameUtils.indexOfLastSeparator(fileName));
    
    RepositoryFile newFile = new RepositoryFile.Builder(fileName).build();
    
    RepositoryFile parentFile = repo.getFile(parentPath);
    
    ByteArrayInputStream bis = new ByteArrayInputStream(text.getBytes("UTF-8"));
    final SimpleRepositoryFileData payload = new SimpleRepositoryFileData(bis, "UTF-8", "text/xml");
    
    repo.createFile(parentFile.getId(), newFile, payload, "Creating dashboard spec");
  }
  
}
